package com.ml.loan.sys.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.google.common.collect.Lists;
import com.ml.loan.common.model.PageResult;
import com.ml.loan.common.redis.RedisService;
import com.ml.loan.common.redis.keys.DictKey;
import com.ml.loan.common.utils.Convert;
import com.ml.loan.sys.dao.SysDictMapper;
import com.ml.loan.sys.model.SysDict;
import com.ml.loan.sys.service.SysDictService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * <p>
 * 字典表 服务实现类
 * </p>
 *
 * @author milian
 * @since 2022-08-12
 */
@Service
public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> implements SysDictService {

    @Autowired
    private RedisService redisService;

    @Override
    public PageResult dictTypes(Integer page, Integer limit, String dictName) {
        LambdaQueryWrapper<SysDict> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDict::getPid, 0);
        if (StringUtils.isNotBlank(dictName)) {
            wrapper.like(SysDict::getDictName, dictName);
        }
        wrapper.orderByAsc(SysDict::getSort);
        Page<SysDict> dictPage = new Page<>(Convert.toInt(page, 1), Convert.toInt(limit, 10));
        IPage<SysDict> iPage = baseMapper.selectPage(dictPage, wrapper);
        return new PageResult<>(iPage.getRecords(), iPage.getTotal());
    }

    @Override
    public PageResult<SysDict> dictDatas(Integer page, Integer limit, Integer pid, String dictDataName, String dictDataCode) {
        LambdaQueryWrapper<SysDict> wrapper = new LambdaQueryWrapper<>();
        if (pid != null) {
            wrapper.eq(SysDict::getPid, pid);
        } else {
            wrapper.ne(SysDict::getPid, 0);
        }
        if (StringUtils.isNotBlank(dictDataCode)) {
            wrapper.like(SysDict::getDictCode, dictDataCode);
        }
        if (StringUtils.isNotBlank(dictDataName)) {
            wrapper.like(SysDict::getDictName, dictDataName);
        }
        wrapper.orderByDesc(SysDict::getStatus);
        wrapper.orderByAsc(SysDict::getSort);
        Page<SysDict> dictPage = new Page<>(Convert.toInt(page, 1), Convert.toInt(limit, 10));
        IPage<SysDict> iPage = baseMapper.selectPage(dictPage, wrapper);
        return new PageResult<>(iPage.getRecords(), iPage.getTotal());
    }

    @Override
    public boolean deleteDictType(Integer id) {
        SysDict before = getById(id);
        if (before == null || before.getPid() != 0) {
            return false;
        }
        LambdaUpdateWrapper<SysDict> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(SysDict::getPid, id);
        if ((!SqlHelper.retBool(count(wrapper)) || remove(wrapper)) && removeById(id)) {
            //清除缓存
            clearRedisCache(before.getDictCode());
            return true;
        }
        return false;
    }

    @Override
    public boolean batchHandleDictData(String ids, Integer state) {
        if (state == -1) {
            return remove(new LambdaUpdateWrapper<SysDict>().in(SysDict::getId, ids.split(",")));
        } else if (state == 1 || state == 0) {
            return update(new LambdaUpdateWrapper<SysDict>().in(SysDict::getId, ids.split(",")).set(SysDict::getStatus, state));
        }
        return false;
    }

    @Override
    public void clearRedisCache(String dictType) {
        redisService.delete(DictKey.dictList, dictType);
    }

    @Override
    public void clearRedisCache(Integer dictDataId) {
        if (dictDataId != null) {
            SysDict dict = getById(dictDataId);
            if (dict != null) {
                //根据DictCode清除缓存
                clearRedisCache(getById(dict.getPid()).getDictCode());
            }
        }
    }

    @Override
    public List<SysDict> getDictList(String dictType) {
        String dicts = redisService.get(DictKey.dictList, dictType, String.class);
        if (StringUtils.isNotBlank(dicts)) {
            return JSON.parseArray(dicts, SysDict.class);
        }
        LambdaQueryWrapper<SysDict> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDict::getDictCode, dictType);
        SysDict one = getOne(wrapper);
        if (one != null) {
            LambdaQueryWrapper<SysDict> dataWrapper = new LambdaQueryWrapper<>();
            dataWrapper.eq(SysDict::getPid, one.getId());
            dataWrapper.eq(SysDict::getStatus, 1);
            dataWrapper.orderByAsc(SysDict::getSort);
            List<SysDict> data = list(dataWrapper);
            if (!data.isEmpty()) {
                redisService.set(DictKey.dictList, dictType, JSON.toJSONString(data));
            }
            return data;
        }
        return Lists.newArrayList();
    }

    @Override
    public String getDictName(String dictType, String dictValue, String defaultValue) {
        List<SysDict> dictList = getDictList(dictType);
        Optional<SysDict> first = dictList.stream().filter(d -> Objects.equals(d.getDictValue(), dictValue)).findFirst();
        if (first.isPresent()) {
            return first.get().getDictName();
        }
        return defaultValue;
    }

    @Override
    public String getDictValue(String dictType, String dictName, String defaultValue) {
        List<SysDict> dictList = getDictList(dictType);
        Optional<SysDict> first = dictList.stream().filter(d -> Objects.equals(dictName, d.getDictName())).findFirst();
        if (first.isPresent()) {
            return first.get().getDictValue();
        }
        return defaultValue;
    }
}
